<?php

/**
 * jQuery Form validator
 * 
 * @category Core
 * @package Core_View
 * @subpackage Helper
 *
 * @version  $Id: JsValidate.php 87 2010-08-29 10:15:50Z vadim.leontiev $
 */
class Core_View_Helper_JsValidate extends Zend_View_Helper_Abstract
{
    /**
     * New js validators
     * @var array
     */
    protected $_validators = array();

    /**
     * @var Zend_Form
     */
    protected $_form = null;

    protected $_rules = array();

    /**
     * Ratio of JS validator and Zend validators
     *
     * @var array
     */
    protected $_ratio = array(
        'Zend_Validate_Date' => 'date: true',
        'Zend_Validate_Digits' => 'digits: true',
        'Zend_Validate_EmailAddresses' => 'email: true',
        'Zend_Validate_StringLength' => 'rangelength: [%min%, %max%]',
        'Zend_Validate_Between' => 'range: [%min%, %max%]'
    );

    /**
     * Set form for validation
     *
     * @param Zend_Form $form [optionaly]
     * @return Core_View_Helper_JsValidate
     */
    public function JsValidate(Zend_Form $form = null)
    {
        if (null !== $form) {
            $this->setForm($form);
        }
        return $this;
    }

    /**
     * Set form for validation
     * @param Zend_Form $form
     * @return Core_View_Helper_JsValidate
     */
    public function setForm(Zend_Form $form)
    {
        $this->_form = $form;
        return $this;
    }

    /**
     * Get registered form
     * 
     * @return Zend_Form
     */
    public function getForm()
    {
        return $this->_form;
    }

    /**
     * Add other validate rules
     *
     * @param array $rules
     * @return Core_View_Helper_JsValidate
     */
    public function addRules(Array $rules)
    {
        $this->_rules = $rules;
        return $this;
    }

    /**
     * Render js scripts
     */
    public function render()
    {
        $this->_addValidateRules();
    }

    /**
     * Get rules from registered Zend_From
     *
     * @return array
     */
    protected function _getRulesFromForm()
    {
        foreach ($this->getForm()->getElements() as $fieldId => $element) {
            if ($element instanceof Zend_Form_Element_Submit) {
                continue;
            }

            if (true === $element->isRequired()){
                $rules['rules'][$fieldId][] = 'required: true';
            }

            foreach ($element->getValidators() as $name => $validator) {
                if (!in_array($name, array_keys($this->_ratio))) {
                    continue;
                }

                $jsValidator = $this->_ratio[$name];
                if (strstr($jsValidator, '%')) {
                    $jsValidator = str_replace('%min%', $validator->getMin(), $jsValidator);
                    $jsValidator = str_replace('%max%', $validator->getMax(), $jsValidator);
                }

                $rules['rules'][$fieldId][] = $jsValidator;
            }
        }
        return $rules;
    }

    /**
     * Create js validate script
     * 
     * @return string
     */
    protected function _addValidateRules()
    {
        $formId = $this->getForm()->getId();
        $rules = $this->_getRulesFromForm();

        $script = '$().ready(function() {
            $("#'.$formId.'").validate({
                rules: {';
                foreach ($rules['rules'] as $name => $rule) {
                    foreach ($rule as $value) {
                        $values[] = $value;
                    }
                    $field[] = $name . ': {' . implode(',', $values) . '}';
                    $values = array();
                }
                $script .= implode(',', $field);
                $script .= '}
            });
        });';

        $this->view->jQuery()->addOnload($script);
        return $this;
    }
}